package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.spi.AudioFileReader;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.tritonus.share.sampled.file.TAudioFileFormat;

import com.audiobuddy.serializables.Song;



import javazoom.spi.PropertiesContainer;
import listeners.SongTableListener;

public class ClientMainJFrame extends JFrame implements ActionListener {

	private GuiController gc;
	
	
	
	//-----------------------------------JBUTTONS--------------------------------
	private JButton btnPlay;
	private JButton btnPause;
	private JButton btnStop;
	private JButton btnNext;
	private JButton btnPrev;


	//------------------------------------JLABELS---------------------------------
	private JLabel lblCurrentSong;


	//------------------------------------JPANELS--------------------------------------
	private JPanel mainPanel;



	private JTable songTable;



	private JScrollPane songScrollPane;



	private JButton btnAddSong;



	private JButton btnRefreshList;
	
	public ClientMainJFrame(GuiController guiController) {
		this.gc = guiController;
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				initGui();
			}
		});
	}
	
	//-------------------------------------------------INITGUI----------------------------------
	protected void initGui() {
		createFrame();
		addContentPanel();
		addControls();
		addSongTable();
		addAddSongBtn();
		
	}
	
	private void addAddSongBtn() {
		btnAddSong = new JButton("Add Song");
		btnAddSong.addActionListener(this);
		mainPanel.add(btnAddSong, BorderLayout.SOUTH);
		
		/*
		btnRefreshList = new JButton("refresh list");
		btnRefreshList.addActionListener(this);
		mainPanel.add(btnRefreshList, BorderLayout.WEST);
		*/
	}

	private void addSongTable() {
		songTable = new JTable(gc.getSongTableModel());
		songScrollPane = new JScrollPane(songTable);
		mainPanel.add(songScrollPane, BorderLayout.CENTER);
		songTable.addMouseListener(new SongTableListener(gc));
		
	}


	private void addControls() {
		JPanel controlPanel = new JPanel();
		controlPanel.setLayout(new FlowLayout());
		controlPanel.setBorder(BorderFactory.createLineBorder(Color.black));
		controlPanel.setSize(700,100);
		
		// Buttons
		btnPlay = new JButton("Play");
		btnPause = new JButton("Pause");
		btnStop = new JButton ("Stop");
		btnNext = new JButton("Next");
		btnPrev = new JButton("Previous");		
		controlPanel.add(btnPlay);
		//controlPanel.add(btnPause);
		controlPanel.add(btnStop);
		controlPanel.add(btnNext);
		controlPanel.add(btnPrev);
		btnPlay.addActionListener(this);
		btnPause.addActionListener(this);
		btnStop.addActionListener(this);
		btnNext.addActionListener(this);
		btnPrev.addActionListener(this);
		//This class is also an ActionListener (implements it) so we don't have to
		//create a new actionListener for each Button.
		//This saves memory usage.
		//All the code should be written in the actionPerformed() method below
		
		// Currently playing
		JLabel playing = new JLabel("Currently playing:");
		controlPanel.add(playing);
		
		lblCurrentSong = new JLabel("");
		controlPanel.add(lblCurrentSong);
		
		mainPanel.add(controlPanel, BorderLayout.NORTH);
	}

	private void addContentPanel() {
		mainPanel = new JPanel(new BorderLayout());
		mainPanel.setSize(new Dimension(800, 600));
		this.setContentPane(mainPanel);
		
	}

	private void createFrame() {
		this.setTitle("AudioBuddy Client 0.1");
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setSize(800, 600);
		this.setResizable(false);
		this.setLocationRelativeTo(null);
		BufferedImage image = null;
		try {
			image = ImageIO.read(this.getClass().getResource("audiobuddy1.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.setIconImage(image);
		
	}
	
	
	
	
	
	
	
	
	
	
	//--------------------------------------------All the button actions in here-----------------------------------------------------------

	@Override
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if(source == btnAddSong){
			String userhome = System.getProperty("user.home");
			JFileChooser fc = new JFileChooser(userhome +"\\Music");
			FileNameExtensionFilter filter = new FileNameExtensionFilter("MP3-bestanden", "mp3");
			fc.setFileFilter(filter);
			
			int status = fc.showOpenDialog(null);
			if(status == JFileChooser.APPROVE_OPTION){
				File f = fc.getSelectedFile();
				try {
					
					AudioInputStream in = AudioSystem.getAudioInputStream(f);
					AudioInputStream din = null;
					AudioFormat baseFormat = in.getFormat();
					AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
							baseFormat.getSampleRate(),
							16,baseFormat.getChannels(),
							baseFormat.getChannels() * 2,
							baseFormat.getSampleRate(),
							false);
					
					AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(f);
					if(baseFileFormat instanceof TAudioFileFormat){
						Map properties =((TAudioFileFormat)baseFileFormat).properties();
						String artist = (String) properties.get("author");
						long dur = (Long) properties.get("duration");
						int filesize = (int) properties.get("mp3.length.bytes");
						String title = (String) properties.get("title");
						System.out.println(artist +" - " + title + " (" +((dur/1000000)%3600)/60 +":"+ (dur/1000000)%60+")");
						System.out.println(f.getAbsolutePath());
						Song song = new Song(title, artist, dur, f.getAbsolutePath(), filesize);
						gc.addSong(song);
						
					}
					
					din = AudioSystem.getAudioInputStream(decodedFormat, in);
					
					AudioFileFormat aff = AudioSystem.getAudioFileFormat(f);
					System.out.println("Audio type: " + aff.getType());
				} catch (UnsupportedAudioFileException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} 
			}
		}
		
		if(source == btnPlay){
			gc.playSong(songTable.getSelectedRow());
		}
		
		if(source == btnPause){
			
		}
		
		if(source == btnNext){
			gc.next();
		}
		
		if(source == btnStop){
			System.out.println("got stop command on gui");
			gc.stop();
		}
		
		if(source == btnPrev){
			gc.previous();
		}
		
		if(source ==btnRefreshList){
			gc.refreshList();
		}
		
	}

	private void rawplay(AudioFormat targetFormat, AudioInputStream din) throws IOException, LineUnavailableException {
		byte[] data = new byte[4096];
		  SourceDataLine line = getLine(targetFormat); 
		  if (line != null)
		  {
			
		    // Start
		    line.start();
		    int nBytesRead = 0, nBytesWritten = 0;
		    while (nBytesRead != -1)
		    {
		        nBytesRead = din.read(data, 0, data.length);
		        if (nBytesRead != -1) nBytesWritten = line.write(data, 0, nBytesRead);
		    }
		    // Stop
		    line.drain();
		    line.stop();
		    line.close();
		    din.close();
		  }
	}
	
	private SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException
	{
	  SourceDataLine res = null;
	  DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
	  res = (SourceDataLine) AudioSystem.getLine(info);
	  res.open(audioFormat);
	  return res;
	}

	public void showCurrentSong(String current) {
		lblCurrentSong.setText(current);
		
	} 

}
